/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.thesis.algorithm;

import java.util.LinkedList;

import java.io.*;
import org.w3c.dom.*;


import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;

/**
 *
 * @author Aya Hikaru
 */
public class Device {

    public String deviceid;
    public String model;
    public String imsi;
    public String mnc;
    public String countryiso;
    public String mcc;
    public String networkoperatorname;
    public String date;
    public String time;
    public String filename;
    public short busNumber;
    public LinkedList<Sample> sampleList = new LinkedList<Sample>();
    public Sample get (int index)
    {
        return this.sampleList.get(index);
    }
    // input filePath without _header.txt part
    public void ReadFromtxt(String filePath) {
        try {
            // read header file
            FileInputStream fstream = new FileInputStream(filePath + "_header.txt");
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String[] info;
            String strline;
            while ((strline = br.readLine()) != null) {
                info = strline.split(" ");
                if (info[0].compareTo("IMEI") == 0) {
                    this.deviceid = info[1];
                } else if (info[0].compareTo("Model") == 0) {
                    this.model = info[1];
                } else if (info[0].compareTo("SubscriberId") == 0) {
                    this.imsi = info[1];
                } else if (info[0].compareTo("Mnc") == 0) {
                    this.mnc = info[1];
                } else if (info[0].compareTo("Mcc") == 0) {
                    this.mcc = info[1];
                } else if (info[0].compareTo("SimCountryIso") == 0) {
                    this.countryiso = info[1];
                } else if (info[0].compareTo("NetworkOperatorName") == 0) {
                    this.networkoperatorname = "";
                    for (int i = 1; i < info.length; i++) {
                        this.networkoperatorname += info[i];
                    }
                } else if (info[0].compareTo("starttime") == 0) {
                    this.time = info[1].substring(0, 2) + info[1].substring(3, 5)
                            + info[1].substring(6, 8);
                } else if (info[0].compareTo("endtime") == 0) {
                    this.date = info[1].substring(0, 4) + info[1].substring(5, 7)
                            + info[1].substring(8, 10);
                } else if (info[0].compareTo("busroute") == 0 && info.length >= 2) {
                    this.busNumber = (short)Integer.parseInt(info[1]);
                } else if (info[0].compareTo("luotdi") == 0 && info.length >= 2 && info[1].compareTo("luotve") == 0 && this.busNumber > 0) {
                    this.busNumber = (short)(-this.busNumber);
                }
            }
            File tmpf = new File(filePath);
            this.filename = tmpf.getName();

            fstream.close();
            in.close();
            br.close();

            // read log file
            fstream = new FileInputStream(filePath + "_log.txt");
            in = new DataInputStream(fstream);
            br = new BufferedReader(new InputStreamReader(in));
            Sample tmpS;
            Cell tmpC;
            while ((strline = br.readLine()) != null) {
                tmpS = new Sample();
                tmpS.time = strline.substring(0, 2) + strline.substring(3, 5)
                        + strline.substring(6, 8);
                strline = br.readLine();
                int number = Integer.parseInt(strline);
                for (int i = 0; i < number; i++) {
                    tmpC = new Cell();
                    strline = br.readLine();
                    info = strline.split(" ");
                    tmpC.id = info[0];
                    tmpC.lac = info[1];
                    tmpC.rssi = info[2];
                    if (info[0].compareTo("0") == 0 || info[1].compareTo("0") == 0 || info[2].compareTo("0") == 0) {
                        continue;
                    }
                    tmpS.cellList.add(tmpC);
                }
                strline = br.readLine();
                info = strline.split(" ");
                tmpS.lng = info[0];
                tmpS.lat = info[1];
                if (info[2].compareTo("null") == 0) {
                    tmpS.speed = null;
                } else {
                    tmpS.speed = info[2];
                }
                if (info[3].compareTo("null") == 0) {
                    tmpS.accuracy = null;
                } else {
                    tmpS.accuracy = info[3];
                }
                strline = br.readLine();

                if (tmpS.lng.compareTo("0") == 0 || tmpS.lat.compareTo("0") == 0) {
                    continue;
                }
                this.sampleList.add(sortRSSI(tmpS));
                //this.sampleList.add(tmpS);
                //System.out.println("DONE");
            }

            fstream.close();
            in.close();
            br.close();

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }

    public void WriteToXML(String xmlFileDirectory) {
        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

            Document doc = docBuilder.newDocument();
            Element rootElement = doc.createElement("dataset");
            doc.appendChild(rootElement);

            Element e = null;
            Element data = null;
            Element device = null;

            // DEVICE INFO
            device = doc.createElement("deviceinfo");
            e = doc.createElement("deviceid");
            e.appendChild(doc.createTextNode("" + deviceid));
            device.appendChild(e);
            e = doc.createElement("model");
            e.appendChild(doc.createTextNode("" + model));
            device.appendChild(e);
            e = doc.createElement("imsi");
            e.appendChild(doc.createTextNode("" + imsi));
            device.appendChild(e);
            e = doc.createElement("mcc");
            e.appendChild(doc.createTextNode("" + mcc));
            device.appendChild(e);
            e = doc.createElement("countryiso");
            e.appendChild(doc.createTextNode("" + countryiso));
            device.appendChild(e);
            e = doc.createElement("mnc");
            e.appendChild(doc.createTextNode("" + mnc));
            device.appendChild(e);
            e = doc.createElement("networkoperatorname");
            e.appendChild(doc.createTextNode("" + networkoperatorname));
            device.appendChild(e);
            e = doc.createElement("date");
            e.appendChild(doc.createTextNode("" + date));
            device.appendChild(e);
            e = doc.createElement("time");
            e.appendChild(doc.createTextNode(" " + time));
            device.appendChild(e);
            rootElement.appendChild(device);

            // SAMPLE LIST
            data = doc.createElement("data");
            Element tmps = null;
            Element tmpl = null;
            Element tmpc = null;
            for (Sample s : sampleList) {
                tmps = doc.createElement("sample");
                e = doc.createElement("time");
                String temp = s.time.substring(0, 2) + ":" + s.time.substring(2, 4) + ":" + s.time.substring(4, 6);
                e.appendChild(doc.createTextNode("" + temp));
                tmps.appendChild(e);
                for (Cell c : s.cellList) {
                    tmpc = doc.createElement("cell");
                    e = doc.createElement("id");
                    e.appendChild(doc.createTextNode("" + c.id));
                    tmpc.appendChild(e);
                    e = doc.createElement("lac");
                    e.appendChild(doc.createTextNode("" + c.lac));
                    tmpc.appendChild(e);
                    e = doc.createElement("rssi");
                    e.appendChild(doc.createTextNode("" + c.rssi));
                    tmpc.appendChild(e);
                    tmps.appendChild(tmpc);
                }

                tmpl = doc.createElement("location");
                e = doc.createElement("lng");
                e.appendChild(doc.createTextNode("" + s.lng));
                tmpl.appendChild(e);
                e = doc.createElement("lat");
                e.appendChild(doc.createTextNode("" + s.lat));
                tmpl.appendChild(e);
                e = doc.createElement("speed");
                e.appendChild(doc.createTextNode("" + s.speed));
                tmpl.appendChild(e);
                e = doc.createElement("accuracy");
                e.appendChild(doc.createTextNode("" + s.accuracy));
                tmpl.appendChild(e);
                tmps.appendChild(tmpl);
                data.appendChild(tmps);

            }

            rootElement.appendChild(data);

            // write the content into xml file
            File xmlFileDir = new File(xmlFileDirectory);
            if (!xmlFileDir.isDirectory() || !xmlFileDir.exists()) {
                return;
            }

            File xmlFilePath = new File(xmlFileDirectory + "\\" + this.filename
                    + ".xml");
            if (!xmlFilePath.exists()) {
                xmlFilePath.createNewFile();
                System.out.println(xmlFilePath.getAbsolutePath());
            }

            TransformerFactory transformerFactory = TransformerFactory
                    .newInstance();
            Transformer tr = transformerFactory.newTransformer();
            tr.setOutputProperty(OutputKeys.INDENT, "yes");
            tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",
                    "2");
            tr.setOutputProperty(OutputKeys.METHOD, "xml");
            tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            tr.setOutputProperty(OutputKeys.VERSION, "1.0");
            DOMSource source = new DOMSource(doc);

            StreamResult result = new StreamResult(xmlFilePath);
            tr.transform(source, result);

            // initialize StreamResult with File object to save to file
            System.out.println(xmlFilePath.getAbsolutePath());

        } catch (ParserConfigurationException pce) {
            pce.printStackTrace();
        } catch (TransformerException tfe) {
            tfe.printStackTrace();
        } catch (Exception tfe) {
            tfe.printStackTrace();
        }
    }

    // sequence of state:busID, observation: cellID
    Sequence getSequence() {
        Sequence seq = new Sequence();
        for (Sample s : sampleList) {
            seq.add(new SequenceElement(
                    (char) Integer.parseInt(s.cellList.getFirst().id), (char) this.busNumber));
        }
        if (seq.size() == 0) {
            return null;
        } else {
            return seq;
        }
    }

//    //check if same lac
//    void checkValid(Sample s) {
//        int lac = Integer.parseInt(s.cellList.get(0).lac);
//        for (int i = 1; i < s.cellList.size(); i++) {
//            if (Integer.parseInt(s.cellList.get(0).lac) != lac)
//            {
//                System.err.println("DIFF LAC OF FILE : " + this.filename);
//                s.print();
//            }
//        }
//    }

    Sample sortRSSI(Sample s) {
        Sample myS = new Sample();
        myS.accuracy = s.accuracy;
        myS.lat = s.lat;
        myS.lng = s.lng;
        myS.speed = s.speed;
        myS.time = s.time;
        LinkedList<Cell> mycellList = new LinkedList<Cell>();
        mycellList.add(s.cellList.get(0));
        int min;
        int index;
        int size = s.cellList.size() - 1;
        for (int i = 0; i < size; i++) {
            index = 1;
            min = Integer.parseInt(s.cellList.get(1).rssi);
            for (int j = 1; j < s.cellList.size(); j++) {
                if (Integer.parseInt(s.cellList.get(j).rssi) < min) {
                    index = j;
                    min = Integer.parseInt(s.cellList.get(j).rssi);
                }
            }
            mycellList.add(new Cell(s.cellList.get(index)));
            s.cellList.remove(index);
        }
        myS.cellList = mycellList;
        return myS;
    }
}
